package com.resource.service.impl;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.resource.redis.RedisUtil;
import com.resource.response.TicketBaseResponse;
import com.resource.service.TicketTokenService;
import com.resource.spring.ApiAssert;
import com.resource.utils.ServiceException;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author: xianggaoxiong
 * @Date: 2021-01-07 19:52
 **/
@Service
@Slf4j
public class TicketTokenServiceImpl implements TicketTokenService {
	@Resource
	private RedisUtil redisUtil;
	@Resource
	private RestTemplate restTemplate;
	@Value("${ticket.app.appId}")
	private String appId;
	@Value("${ticket.app.appKey}")
	private String appKey;

	private final static String TICKET_TOKEN = "mc:ticket:appId:%s:token";

	private final static String TOKEN_URL = "https://www.sobot.com/api/get_token";

	@Override
	public String getToken() throws ServiceException {
		Object token = redisUtil.get(String.format(TICKET_TOKEN, appId));
		if (ObjectUtil.isNotEmpty(token)) {
			return String.valueOf(token);
		}
		String sign = "";
		Long currentTime = System.currentTimeMillis();
		try {
			String key = appId + currentTime + appKey;
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(key.getBytes());
			sign = new BigInteger(1, md.digest()).toString(16);
		} catch (NoSuchAlgorithmException e) {
			log.error("智齿获取签名失败",e);
			throw new ServiceException("获取签名失败");
		}
		String url = new StringBuilder(TOKEN_URL).append("?appid=").append(appId).append("&create_time=")
				.append(currentTime).append("&sign=").append(sign).toString();
		try {
			TicketBaseResponse responseToken = restTemplate.getForObject(url, TicketBaseResponse.class);
			ApiAssert.isFalse("获取token失败",ObjectUtil.isNotNull(responseToken) &&"000000".equals(responseToken.getRet_code()));
			String resultToken = (String) responseToken.getItem().get("token");
			redisUtil.set(String.format(String.format(TICKET_TOKEN, appId)), responseToken.getItem().get("token"),
					Long.valueOf((String) responseToken.getItem().get("expires_in")) - 600);
			return resultToken;
		} catch (RestClientException e) {
			log.error("智齿获取token失败",e);
			throw new ServiceException("获取token失败");
		}
	}
}
